package com.shanzmoo.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.base.constant.Constant;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.base.constant.PayStatusConstant;
import com.shanzmoo.core.config.pay.TradePayProp;
import com.shanzmoo.core.service.ICommonPayService;
import com.shanzmoo.db.order.entity.bo.PayMoneyResultBO;
import com.shanzmoo.db.trade.entity.PayOrderEntity;
import com.shanzmoo.core.domain.pay.AliPayOrdeTradeDto;
import com.shanzmoo.core.domain.pay.AliPayOrderQrCodeDto;
import com.shanzmoo.core.domain.pay.PayOrderEntityLocalUtil;
import com.shanzmoo.core.domain.pay.PayResultResp;
import com.shanzmoo.db.trade.service.IPayOrderService;
import com.shanzmoo.core.pay.sdk.alipay.config.Configs;
import com.shanzmoo.core.pay.sdk.alipay.model.TradeStatus;
import com.shanzmoo.core.pay.sdk.alipay.model.builder.AlipayTradePayRequestBuilder;
import com.shanzmoo.core.pay.sdk.alipay.model.builder.AlipayTradePrecreateRequestBuilder;
import com.shanzmoo.core.pay.sdk.alipay.model.builder.AlipayTradeQueryRequestBuilder;
import com.shanzmoo.core.pay.sdk.alipay.model.result.AlipayF2FPayResult;
import com.shanzmoo.core.pay.sdk.alipay.model.result.AlipayF2FPrecreateResult;
import com.shanzmoo.core.pay.sdk.alipay.model.result.AlipayF2FQueryResult;
import com.shanzmoo.core.pay.sdk.alipay.service.AlipayTradeService;
import com.shanzmoo.core.pay.sdk.alipay.service.impl.AlipayTradeServiceImpl;
import com.shanzmoo.core.pay.sdk.alipay.utils.ZxingUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * 阿里支付宝，支付实现类
 *
 * @author Gzhao
 * @date 2020/12/6
 */
@Slf4j
//@Service("aliPayService")
public class AliCommonPayServiceImpl implements ICommonPayService {

    @Resource
    private TradePayProp tradePayProp;

    // 支付宝当面付2.0服务
    private static AlipayTradeService tradeService;

    @Autowired
    private IPayOrderService payOrderService;

    @PostConstruct
    private void init() {
        Configs.init("zfbinfo.properties");
        tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
    }

    @Override
    public SResponse<String> tradeQrCode() {

        AliPayOrderQrCodeDto aliPayOrderQrCodeDto = AliPayOrderQrCodeDto.create(PayOrderEntityLocalUtil.getPayOrderEntity());

        // 创建扫码支付请求builder，设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(aliPayOrderQrCodeDto.getSubject())
                .setTotalAmount(aliPayOrderQrCodeDto.getTotalAmount())
                .setOutTradeNo(aliPayOrderQrCodeDto.getOutTradeNo())
                .setTimeoutExpress(tradePayProp.getQrCodePayTimeout())
                .setStoreId(String.valueOf(CurrentUserCache.getOutletId()))
                .setNotifyUrl(tradePayProp.getAliPayCallBack());

        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        if (result.getTradeStatus() == TradeStatus.SUCCESS) {
            AlipayTradePrecreateResponse response = result.getResponse();
            log.info("支付宝预下单成功，返回数据：{}", JSON.toJSONString(response));

            return SResponse.ok(response.getQrCode());
        } else {
            log.error("支付宝预下单是吧，返回数据：{}", JSON.toJSONString(result.getResponse()));
            return SResponse.fail(Constant.ERRCODE_LOGIC, "支付宝预下单失败");
        }
    }

    @Override
    public SResponse<PayMoneyResultBO> tradePay(String authCode) {
        PayOrderEntity payOrderEntity = PayOrderEntityLocalUtil.getPayOrderEntity();

        AliPayOrdeTradeDto tradeDto = AliPayOrdeTradeDto.create(payOrderEntity, authCode);

        // 创建条码支付请求builder，设置请求参数
        AlipayTradePayRequestBuilder builder = new AlipayTradePayRequestBuilder()
                .setOutTradeNo(tradeDto.getOutTradeNo())
                .setSubject(tradeDto.getSubject())
                .setAuthCode(tradeDto.getAuthCode())
                .setTotalAmount(tradeDto.getTotalAmount())
                .setStoreId(String.valueOf(tradeDto.getStoreId()))
                .setTimeoutExpress(tradePayProp.getOffLinePayTimeout());

        PayMoneyResultBO resultBO = new PayMoneyResultBO();

        // 调用tradePay方法获取当面付应答
        AlipayF2FPayResult result = tradeService.tradePay(builder);
        boolean success = result.getTradeStatus() == TradeStatus.SUCCESS;
        if (success) {
            log.info("支付宝扫码支付成功");
            SResponse<Boolean> re = payOrderService.updatePaySuccessStatusByNo(tradeDto.getOutTradeNo());
            if (re.getData()) {
                return SResponse.ok(resultBO);
            } else {
                log.error("支付宝扫码支付失败! 业务逻辑处理异常");
                return SResponse.fail(Constant.ERRCODE_LOGIC, "业务逻辑处理异常");
            }
        } else {
            log.error("支付宝扫码支付失败, 响应结果：{}", JSON.toJSONString(result));
            return SResponse.fail(Constant.ERRCODE_LOGIC, "支付宝扫码支付失败, 响应结果：" + JSON.toJSONString(result));
        }
    }

    @Override
    public SResponse<PayResultResp> queryPayResult(String payNo) {

        // 创建查询请求builder，设置请求参数
        AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
                .setOutTradeNo(payNo);

        AlipayF2FQueryResult result = tradeService.queryTradeResult(builder);
        log.info("支付宝订单：{}，查询结果：{}", payNo, JSON.toJSONString(result));

        PayOrderEntity payOrder = PayOrderEntityLocalUtil.getPayOrderEntity();
        PayOrderEntityLocalUtil.setQueryRespBody(JSON.toJSONString(result));

        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("查询返回该订单支付成功: )");

                AlipayTradeQueryResponse response = result.getResponse();

                log.info(response.getTradeStatus());

                /**
                 * 交易状态：
                 *      WAIT_BUYER_PAY（交易创建，等待买家付款）
                 *      TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）
                 *      TRADE_SUCCESS（交易支付成功）
                 *      TRADE_FINISHED（交易结束，不可退款）
                 */
                if ("TRADE_SUCCESS".equals(response.getTradeStatus())){
                    payOrder.setPayStatus(PayStatusConstant.PAY_SUCCESS);
                    return SResponse.ok(PayResultResp.createSuccess());

                } else if ("TRADE_CLOSED".equals(response.getTradeStatus()) || "TRADE_FINISHED".equals(response.getTradeStatus())){
                    payOrder.setPayStatus(PayStatusConstant.PAY_Fail);
                    return SResponse.ok(PayResultResp.createFail("交易关闭"));

                } else {
                    return SResponse.ok(PayResultResp.createFail("等待买家付款"));
                }


            case FAILED:
                log.error("查询返回该订单支付失败或被关闭!!!");
                return SResponse.ok(PayResultResp.createFail("查询返回该订单支付失败或被关闭"));

            case UNKNOWN:
                log.error("系统异常，订单支付状态未知!!!");
                return SResponse.ok(PayResultResp.createFail("系统异常，订单支付状态未知"));

            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                return SResponse.fail(Constant.ERRCODE_LOGIC, "系统异常，订单支付状态未知");
        }
    }

    /**
     * 生成二维码图片
     *
     * @param outTradeNo
     * @param qrCode
     */
    private void generateQrCodeImage(String outTradeNo, String qrCode) {
        String filePath = String.format("E:/test/alipay/qr-%s.png", outTradeNo);
        log.info("filePath:" + filePath);
        ZxingUtils.getQRCodeImge(qrCode, 256, filePath);
    }
}
